package com.scwatch.ext.web.back;

import com.alibaba.fastjson.JSONObject;
import com.scwatch.common.web.Servlets;
import com.scwatch.core.SpringContextUtil;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.Site;
import com.scwatch.core.domain.User;
import com.scwatch.core.support.Context;
import com.scwatch.ext.domain.Collect;
import com.scwatch.ext.domain.ScheduleJob;
import com.scwatch.ext.service.CollectService;
import com.scwatch.ext.service.ScheduleJobService;
import com.scwatch.ext.service.impl.JobTaskServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.CronScheduleBuilder;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.scwatch.core.constant.Constants.*;


@Controller
@RequestMapping("/ext/task")
public class JobTaskController {
    // 日志记录器
    public final Logger log = Logger.getLogger(this.getClass());

    @Autowired(required = true)
    private JobTaskServiceImpl taskService;

    @Autowired
    private ScheduleJobService scheduleJobMapper;

    /*------------------------------------[ 验证名称 ]--------------------------------*/
    @RequiresPermissions("ext:task:jobNameView")
    @RequestMapping("jobNameView.do")
    public @ResponseBody
    String jobNameView(//获取所有计划中的任务  所有正在运行的job
                     HttpServletRequest request) {
        JSONObject json = new JSONObject();
        json.put("flag", false);
        String jobName = request.getParameter("jobName");

        List<ScheduleJob> list = scheduleJobMapper.findByjobName(jobName);
        if(list.size()>0){
            json.put("flag", true);
            json.put("msg","已存在.....");
        }
        return json.toJSONString();
    }


    /*----------------------[   系统 bean中的定时     ]-----------------*/
    @RequiresPermissions("ext:task:getAllJob")
    @RequestMapping("getAllJob.do")
    public String getAllJob(//获取所有计划中的任务  所有正在运行的job
                            HttpServletRequest request, org.springframework.ui.Model modelMap) {

        //对应站点
        Integer siteId = Context.getCurrentSiteId();
        String isType = request.getParameter("isType");// 1、ITP 2、TRZ
        List<ScheduleJob> list = null;
        try {
            if ("ITP".equals(isType)) {
                list = taskService.getAllJob(siteId);
            }
            if ("TRZ".equals(isType)) {
                list = taskService.getRunningJob(siteId);
            }
        } catch (SchedulerException e) {

            log.error("getAllJob 异常：" + e.getMessage());

        } finally {

            modelMap.addAttribute("typeList", list);
            modelMap.addAttribute("isType", isType);

            return "ext/task/System_task_list";

        }
    }

    @RequiresPermissions(value = {
            "ext:task:setUpJob",
            "ext:task:setUpJobDel",
            "ext:task:setUpJobRestore",
            "ext:task:setUpJobSuspended",
            "ext:task:setUpJobExecuted"
    },logical = Logical.OR)
    @RequestMapping("setUpJob.do")
    public String setUpJob(HttpServletRequest request,
                           Integer[] ids,
                           Integer isRestore,
                           String cmd,
                           RedirectAttributes ra) { //设置 暂停一个job  恢复一个job  立即执行

        String isType = request.getParameter("isType");// 1、ITP 2、TRZ

        for (Integer id : ids) {
            ScheduleJob scheduleJob = scheduleJobMapper.selectByPrimaryKey(id);
            try {
                if (isRestore != null) {
                    //	 * 执行状态 1、恢复 2、暂停 0、立即执行
                    if (isRestore == 1) {
                        taskService.resumeJob(scheduleJob);
                    } else if (isRestore == 2) {
                        taskService.pauseJob(scheduleJob);
                    } else if (isRestore == 0) {
                        taskService.runAJobNow(scheduleJob);
                    }
                    scheduleJob.setIsRestore(isRestore);
                    scheduleJob.setUpdateTime(new Date());//更新时间
                    scheduleJobMapper.insert(scheduleJob);
                }
                // 删除JOB 中的方法
                if (StringUtils.isNotBlank(cmd)) {
                    if ("stop".equals(cmd)) {
                        taskService.changeStatus(scheduleJob.getId(), cmd);
                    }
                }

            } catch (SchedulerException e) {

                log.error("setUpJob 异常：" + e.getMessage());

            }
        }

        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);

        ra.addAttribute("isType", StringUtils.isNotBlank(isType) ? isType : "ITP");

        return "redirect:getAllJob.do";

    }


    /*----------------------[   启动未进行 定时任务管理     ]-----------------*/

    @RequiresPermissions("ext:task:list")
    @RequestMapping("list.do")
    public String list(
            @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
            HttpServletRequest request, org.springframework.ui.Model modelMap) {

        Integer siteId = Context.getCurrentSiteId();

        Map<String, String[]> params = Servlets.getParamValuesMap(request,
                Constants.SEARCH_PREFIX);
//        params.put("EQ_jobStatus", new String[]{"0"});//只查询 没有执行的数据

        Page<ScheduleJob> pagedList = scheduleJobMapper.findAll(siteId, params, pageable);//taskService.getAllTask();

        modelMap.addAttribute("pagedList", pagedList);

        return "ext/task/quertz_task_list";
    }


    @RequiresPermissions("ext:task:changeJobStatus")
    @RequestMapping("changeJobStatus.do")
    public String changeJobStatus(HttpServletRequest request, Integer[] ids, String cmd, RedirectAttributes ra) {
        try {

            for (Integer jobId : ids) {
                taskService.changeStatus(jobId, cmd);
            }

        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
        }

        ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);

        return "redirect:list.do";
    }

    @RequiresPermissions("ext:task:delete")
    @RequestMapping("delete.do")
    public String changeJobStatus(HttpServletRequest request, Integer[] ids, RedirectAttributes ra) {

        try {
            scheduleJobMapper.deleteByPrimaryKey(ids);
            ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);

        } catch (Exception e) {

            ra.addFlashAttribute(MESSAGE, OPERATION_FAILURE);

        } finally {
            return "redirect:list.do";
        }
    }


    @RequiresPermissions("ext:task:create")
    @RequestMapping("create.do")
    public String create(HttpServletRequest request, Integer position, org.springframework.ui.Model modelMap) {

        modelMap.addAttribute(OPRT, CREATE);
        modelMap.addAttribute("position", position);

        return "ext/task/quertz_task_form";
    }

    @RequiresPermissions("ext:task:edit")
    @RequestMapping("edit.do")
    public String edit(HttpServletRequest request, Integer id, Integer position, org.springframework.ui.Model modelMap) {

        ScheduleJob scheduleJob = taskService.getTaskById(id);
        modelMap.addAttribute(OPRT, EDIT);

        modelMap.addAttribute("bean", scheduleJob);
        modelMap.addAttribute("position", position);
        return "ext/task/quertz_task_form";
    }


    @RequiresPermissions(value = {
            "ext:task:save",
            "ext:task:update"
    },logical = Logical.OR)
    @RequestMapping("saveOrUpdate.do")
    public String saveOrUpdate(HttpServletRequest request, Integer position, ScheduleJob scheduleJob, String redirect, RedirectAttributes ra) {
        Site site = Context.getCurrentSite();
        User user = Context.getCurrentUser();
        JSONObject retObj = new JSONObject();
        retObj.put("msg", SAVE_SUCCESS);
        try {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
        } catch (Exception e) {
            retObj.put("msg", "cron表达式有误，不能被解析！");
            return retObj.toJSONString();
        }
        Object obj = null;
        try {
            if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
                obj = SpringContextUtil.getBean(scheduleJob.getSpringId());
            } else {
                Class clazz = Class.forName(scheduleJob.getBeanClass());
                obj = clazz.newInstance();
            }
        } catch (Exception e) {
            // do nothing.........
        }
        if (obj == null) {
            retObj.put("msg", "未找到目标类！");
        } else {
            Class clazz = obj.getClass();
            Method method = null;
            try {
                method = clazz.getMethod(scheduleJob.getMethodName());
            } catch (Exception e) {
                try {
                    method = clazz.getMethod(scheduleJob.getMethodName(),Integer.class);
                } catch (Exception e1) {
                    try {
                        method = clazz.getMethod(scheduleJob.getMethodName(),String.class);
                    } catch (Exception e2) {
                        // do nothing.....
                    }
                }
            }
            if (method == null) {
                retObj.put("msg", "未找到目标方法！");
            }
        }

        if (scheduleJob.getId() == null) {
            /*-------[ 添加到 bean 中]----------*/
            if (ScheduleJob.STATUS_RUNNING.equals(scheduleJob.getJobStatus())) {
                try {
                    taskService.addJob(scheduleJob);
                } catch (SchedulerException e) {
                    e.printStackTrace();
                }
            }
        }
//        String parSet = scheduleJob.getParSet();
//        if(StringUtils.isNotBlank(parSet)) {
//            switch (parSet) {
//                case "add":
//                case "start":
//                case "":
//                    Collect collect =  service.get(Integer.parseInt(parSet));
//                    collect.setStatus(0);
//                    service.update(collect,null);
//            }
//        }


        ScheduleJob scheduleJob1 = null;
        try {
            scheduleJob.setSite(site);
            scheduleJob.setUser(user);
            scheduleJob1 = taskService.addTask(scheduleJob);


        } catch (Exception e) {
            e.printStackTrace();
            retObj.put("msg", "保存失败，检查 name group 组合是否有重复！");
            return retObj.toJSONString();
        }

        ra.addFlashAttribute(MESSAGE, retObj.getString("msg"));
        if (Constants.REDIRECT_LIST.equals(redirect)) {

            ra.addAttribute("position", position);
            return "redirect:list.do";
        } else if (Constants.REDIRECT_EDIT.equals(redirect)) {

            ra.addAttribute("id", scheduleJob1.getId());
            return "redirect:edit.do";
        } else {

            return "redirect:create.do";
        }
    }
    @Autowired
    private CollectService service;

    @RequiresPermissions("ext:task:updateCron")
    @RequestMapping("updateCron.do")
    public @ResponseBody
    String updateCron(HttpServletRequest request, Integer jobId, String cron) {
        JSONObject retObj = new JSONObject();
        retObj.put("flag", false);
        try {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        } catch (Exception e) {
            retObj.put("msg", "cron表达式有误，不能被解析！");
            return retObj.toJSONString();
        }
        try {
            taskService.updateCron(jobId, cron);
        } catch (SchedulerException e) {
            retObj.put("msg", "cron更新失败！");
            return retObj.toJSONString();
        }
        retObj.put("flag", true);
        return retObj.toJSONString();
    }
}
